/*
 * Copyright 2014 OGIS-RI All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package jp.co.ogis_ri.optaplanner.vehiclerouting.domain.core;

import jp.co.ogis_ri.optaplanner.vehiclerouting.domain.Location;
import jp.co.ogis_ri.optaplanner.vehiclerouting.domain.Vehicle;

import org.optaplanner.core.api.domain.entity.PlanningEntity;
import org.optaplanner.core.api.domain.variable.InverseRelationShadowVariable;
import org.optaplanner.core.api.domain.variable.PlanningVariable;

@PlanningEntity
public abstract class TimeWindowedStep extends AbstractPersistable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * Shadow variables: 次の地点
	 */
	protected ChainedTimeWindowedStep nextStep;

	/**
	 * 準備完了時間
	 */
	protected int readyTime;

	/**
	 * 期限時間（荷物出荷期限や、トラックの稼働できる時間など）
	 */
	protected int dueTime;

	/**
	 * 出発時間を取得する
	 */
	abstract public Integer getDepartureTime();

	/**
	 * 準備完了時間を取得する
	 * 
	 * @return
	 */
	public int getReadyTime() {
		return this.readyTime;
	}

	/**
	 * 準備完了時間を設定する
	 * 
	 * @param readyTime
	 */
	public void setReadyTime(final int readyTime) {
		this.readyTime = readyTime;
	}

	/**
	 * 期限時間（荷物出荷期限や、トラックの稼働できる時間など）を取得する
	 * 
	 * @return
	 */
	public int getDueTime() {
		return this.dueTime;
	}

	/**
	 * 期限時間（荷物出荷期限や、トラックの稼働できる時間など）を設定する
	 * 
	 * @param dueTime
	 */
	public void setDueTime(final int dueTime) {
		this.dueTime = dueTime;
	}

	/**
	 * この地点の位置情報を取得する
	 * 
	 * @return never null
	 */
	abstract public Location getLocation();

	/**
	 * この地点を担当する車を取得する
	 * 
	 * @return sometimes null
	 */
	abstract public Vehicle getVehicle();

	/**
	 * 次の地点を取得する。{@link PlanningVariable}のpreviousStepに対応して設定される
	 */
	@InverseRelationShadowVariable(sourceVariableName = "previousStep")
	public ChainedTimeWindowedStep getNextStep() {
		return this.nextStep;
	}

	public void setNextStep(final ChainedTimeWindowedStep nextStep) {
		this.nextStep = nextStep;
	}
}
